require "report/Report"
require "utils/Stat"
require "rsruby"

class CorrelationAnalysis
  
  def analysis(dir, nameX, nameY, x, y)
    scatter_plot(dir, nameX, nameY, x, y)
    _analysis(dir, "#{nameX}-#{nameY}-linear", :linear, x, y)
    _analysis(dir, "#{nameX}-#{nameY}-quadratic", :quadratic, x, y)
    _analysis(dir, "#{nameX}-#{nameY}-cubic", :cubic, x, y)
  end
  
  def scatter_plot(dir, nameX, nameY, x, y)
    Dir.mkdir(dir) unless File.directory?(dir)
    subjects = x.keys
    r = RSRuby.instance
    
    w = Math.sqrt(subjects.size).ceil
    
    r.png("#{dir}/#{nameX}-#{nameY}-scatter-plot.png", w*500, w*500)
    
    r.eval_R("par(mfrow=c(#{w},#{w}))")

    subjects.each { |s|
      a, b = x[s], y[s]
      r.assign("x", a)
      r.assign("y", b)
      r.plot(a, b, :xlab=>nameX, :ylab=>nameY, :main=>s)    
    }
    r.eval_R("dev.off()")   
  end
  
  
  def _analysis(dir, name, analysis, x, y)
    #create a directory
    Dir.mkdir(dir) unless File.directory?(dir)
    report = Report.new(dir, name)
    
    correlations, stat = self.send(analysis, x, y)
 
    corrs = []       
    correlations.each_pair { |s, cor|
      stat += "<tr><td>#{s}</td><td>#{cor}</td></tr>"
      corrs << cor
    }
    stat += "<tr><td>AVERAGE</td><td>#{average(corrs)}</td></tr>"
    stat += "</tbody></table><br/>"
    
    report.new_section("Correlation: #{name}", stat, nil)
    report.to_html
  end
  

  # Linear Correlation
  def linear(x, y)
    subjects = x.keys
    r = RSRuby.instance
    correlations = {}

    subjects.each { |s|
      correlations[s] = r.cor(x[s], y[s] )
    }
    
    stat = "<table border=\"1\">"+
           "<thead>"+
           "<tr>" +
           "<td>Subjects</td><td>linear correlation (r)</td>" +
           "</tr>" +
           "</thead><tbody>" 

    return correlations, stat       
  end
  
  # quadratic Correlation
  def quadratic(x, y)
    subjects = x.keys
    r = RSRuby.instance
    correlations = {}

    subjects.each { |s|
      correlations[s] = r.cor(x[s].collect{|z| z**2} , y[s].collect {|z| z**2} )
    }

    stat = "<table border=\"1\">"+
    "<thead>"+
    "<tr>" +
    "<td>Subjects</td><td>quadratic correlation (r^2)</td>" +
    "</tr>" +
    "</thead><tbody>"

    return correlations, stat
  end

  
  # cubic Correlation
  def cubic(x, y)
    subjects = x.keys
    r = RSRuby.instance
    correlations = {}

    subjects.each { |s|
      correlations[s] = r.cor(x[s].collect{|z| z**3} , y[s].collect {|z| z**3} )
    }

    stat = "<table border=\"1\">"+
    "<thead>"+
    "<tr>" +
    "<td>Subjects</td><td>quadratic correlation (r^3)</td>" +
    "</tr>" +
    "</thead><tbody>"

    return correlations, stat
  end
end